using System;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 事件中心，用于解耦不同模块之间的通信
/// </summary>
public class EventCenter
{
    // 声明一个静态实例，使事件中心成为单例
    private static EventCenter _instance;
    public static EventCenter Instance
    {
        get
        {
            if (_instance == null)
                _instance = new EventCenter();
            return _instance;
        }
    }

    // 定义事件字典，用于存储事件和对应的监听器列表
    private Dictionary<string, Delegate> _eventDictionary;

    /// <summary>
    /// 私有构造函数，防止外部实例化
    /// </summary>
    private EventCenter()
    {
        _eventDictionary = new Dictionary<string, Delegate>();
    }

    #region 添加监听器

    /// <summary>
    /// 添加无参事件监听器
    /// </summary>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void AddListener(string eventName, Action listener)
    {
        if (!Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary.Add(eventName, null);
        }
        Instance._eventDictionary[eventName] = (Action)Instance._eventDictionary[eventName] + listener;
    }

    /// <summary>
    /// 添加带一个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void AddListener<T>(string eventName, Action<T> listener)
    {
        if (!Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary.Add(eventName, null);
        }
        Instance._eventDictionary[eventName] = (Action<T>)Instance._eventDictionary[eventName] + listener;
    }

    /// <summary>
    /// 添加带两个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void AddListener<T, U>(string eventName, Action<T, U> listener)
    {
        if (!Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary.Add(eventName, null);
        }
        Instance._eventDictionary[eventName] = (Action<T, U>)Instance._eventDictionary[eventName] + listener;
    }

    /// <summary>
    /// 添加带三个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <typeparam name="V">参数3类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void AddListener<T, U, V>(string eventName, Action<T, U, V> listener)
    {
        if (!Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary.Add(eventName, null);
        }
        Instance._eventDictionary[eventName] = (Action<T, U, V>)Instance._eventDictionary[eventName] + listener;
    }

    #endregion

    #region 移除监听器

    /// <summary>
    /// 移除无参事件监听器
    /// </summary>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void RemoveListener(string eventName, Action listener)
    {
        if (Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary[eventName] = (Action)Instance._eventDictionary[eventName] - listener;
        }
    }

    /// <summary>
    /// 移除带一个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void RemoveListener<T>(string eventName, Action<T> listener)
    {
        if (Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary[eventName] = (Action<T>)Instance._eventDictionary[eventName] - listener;
        }
    }

    /// <summary>
    /// 移除带两个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void RemoveListener<T, U>(string eventName, Action<T, U> listener)
    {
        if (Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary[eventName] = (Action<T, U>)Instance._eventDictionary[eventName] - listener;
        }
    }

    /// <summary>
    /// 移除带三个参数的事件监听器
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <typeparam name="V">参数3类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="listener">监听器回调函数</param>
    public static void RemoveListener<T, U, V>(string eventName, Action<T, U, V> listener)
    {
        if (Instance._eventDictionary.ContainsKey(eventName))
        {
            Instance._eventDictionary[eventName] = (Action<T, U, V>)Instance._eventDictionary[eventName] - listener;
        }
    }

    #endregion

    #region 触发事件

    /// <summary>
    /// 触发无参事件
    /// </summary>
    /// <param name="eventName">事件名称</param>
    public static void TriggerEvent(string eventName)
    {
        Delegate d;
        if (Instance._eventDictionary.TryGetValue(eventName, out d))
        {
            Action callback = d as Action;
            if (callback != null)
            {
                callback();
            }
            else
            {
                Debug.LogError("TriggerEvent<" + eventName + ">时出现类型不匹配错误");
            }
        }
    }

    /// <summary>
    /// 触发带一个参数的事件
    /// </summary>
    /// <typeparam name="T">参数类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="arg">参数值</param>
    public static void TriggerEvent<T>(string eventName, T arg)
    {
        Delegate d;
        if (Instance._eventDictionary.TryGetValue(eventName, out d))
        {
            Action<T> callback = d as Action<T>;
            if (callback != null)
            {
                callback(arg);
            }
            else
            {
                Debug.LogError("TriggerEvent<" + eventName + ">时出现类型不匹配错误");
            }
        }
    }

    /// <summary>
    /// 触发带两个参数的事件
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="arg1">参数1值</param>
    /// <param name="arg2">参数2值</param>
    public static void TriggerEvent<T, U>(string eventName, T arg1, U arg2)
    {
        Delegate d;
        if (Instance._eventDictionary.TryGetValue(eventName, out d))
        {
            Action<T, U> callback = d as Action<T, U>;
            if (callback != null)
            {
                callback(arg1, arg2);
            }
            else
            {
                Debug.LogError("TriggerEvent<" + eventName + ">时出现类型不匹配错误");
            }
        }
    }

    /// <summary>
    /// 触发带三个参数的事件
    /// </summary>
    /// <typeparam name="T">参数1类型</typeparam>
    /// <typeparam name="U">参数2类型</typeparam>
    /// <typeparam name="V">参数3类型</typeparam>
    /// <param name="eventName">事件名称</param>
    /// <param name="arg1">参数1值</param>
    /// <param name="arg2">参数2值</param>
    /// <param name="arg3">参数3值</param>
    public static void TriggerEvent<T, U, V>(string eventName, T arg1, U arg2, V arg3)
    {
        Delegate d;
        if (Instance._eventDictionary.TryGetValue(eventName, out d))
        {
            Action<T, U, V> callback = d as Action<T, U, V>;
            if (callback != null)
            {
                callback(arg1, arg2, arg3);
            }
            else
            {
                Debug.LogError("TriggerEvent<" + eventName + ">时出现类型不匹配错误");
            }
        }
    }

    #endregion
}